DynamoDB、Cassandra互換のOSS NoSQL「Scylla」を使ってみる
Scyllaとは
Scyllaはオープンソースのワイドカラム型のデータストアです。 Apache CassandraやAmazon DynamoDBとの互換性があります。 Cassandraと同様にクラスタ構成が可能ですが、ノードの性能が高いため、より少ないノード数で同様のパフォーマンスが出せるようです。
公式ホームページでは以下のように謳っています。
World's Fastest NoSQL Database
Power your applications with ultra-low latency & extremely high throughput
速い!強い!そんなDBらしいです。
今回はあくまでもDynamoDBの代わりとして使いますが、メインはCassandraの方みたいです。 互換性があるのでエンドポイントを書き換えるだけでほとんどコード変更なしでDBを変更することができるみたいです。 (データのマイグレーション等の必要はあるでしょうが)
つかってみる
今回はDockerを使用してDynamoDBの代わりに使ってみます。
$ docker run -it -p 8000:8000 --name scylla \ scylladb/scylla \ --alternator-port 8000 \ --alternator-write-isolation only_rmw_uses_lwt
デフォルトだとINFOのログが大量に発生してびっくりしました。
DynamoDBの互換機能はalternator
と呼ばれており、--alternator-port
などはそれ用の設定です。
これとは別にCassandra用の機能も同時に動いています。
以下のような感じでログを見てエラーが発生していなければ概ね大丈夫だと思います。
$ docker logs scylla 2>&1 | grep ERROR
この時自分はエラーがでてハマりました。詳細は一番最後に書いておきます。
せっかくなのでCassandraのクライアントを使って動作確認をしてみます。
$ docker exec -it scylla cqlsh Connected to at 172.17.0.2:9042. [cqlsh 5.0.1 | Cassandra 3.0.8 | CQL spec 3.3.1 | Native protocol v4] Use HELP for help.
無事に接続できたみたいです。
最後にドキュメントを参考にDynamoDBとして使用してみます。 やっているのは次のことです。
- テーブルの作成
- データの書き込み
- データの読み込み
import boto3 dynamodb = boto3.resource( 'dynamodb', endpoint_url='http://localhost:8000', region_name='None', aws_access_key_id='None', aws_secret_access_key='None' ) dynamodb.create_table( AttributeDefinitions=[ { 'AttributeName': 'key', 'AttributeType': 'S' }, ], BillingMode='PAY_PER_REQUEST', TableName='usertable', KeySchema=[ { 'AttributeName': 'key', 'KeyType': 'HASH' }, ]) dynamodb.batch_write_item(RequestItems={ 'usertable': [ { 'PutRequest': { 'Item': { 'key': 'test', 'x': {'hello': 'world'} } }, } ] }) print(dynamodb.batch_get_item(RequestItems={ 'usertable': {'Keys': [{'key': 'test'}]} }))
endpoint_url
をlocalhost:8000
にしています。
これはDockerで動いてるScyllaの8000番がバインドされているポートです。
実行してみます。
$ python3 sample.py { 'Responses': { 'usertable': [ {'key': 'test', 'x': {'hello': 'world'}} ] }, 'UnprocessedKeys': {}, 'ResponseMetadata': { 'HTTPStatusCode': 200, 'HTTPHeaders': { 'content-length': '105', 'content-type': 'application/json', 'date': 'Wed, 11 Aug 2021 09:03:48 GMT', 'server': 'Seastar httpd' }, 'RetryAttempts': 0 } }
無事に動いているようです。
ハマったところ
Scyllaサーバーを動かした時に以下のようなエラーが発生しました。
seastar - Could not setup Async I/O: Resource temporarily unavailable. The most common cause is not enough request capacity in /proc/sys/fs/aio-max-nr. Try increasing that number or reducing the amount of logical CPUs available for your application
CPUのコア数とカーネルパラメータによってはうまく起動しない場合があるみたいです。
使用するコア数を減らすか、カーネルパラメータを変えると自分は動きました。
変更するカーネルパラメータはfs.aio-max-nr
です。
自分の環境(Ubuntu20.04 8コア)では65536
でしたが、1048576
に変えたところ動きました。
Dockerで動かしていてもこのパラメータはホスト側で変更しないといけないらしく、ホスト側で設定しました。
$ sudo sysctl -w fs.aio-max-nr=1048576
必要値の計算式はここにかいてあります。
感想
おもったよりも簡単に動きました。 自分はCassandraを使ったことないので今回はDynamoDBの代わりとして使用しましたが、勉強してCassandaraとしても使ってみたいです。 現代のコンピュータのアーキテクチャに合わせて設計されているみたいなのでパフォーマンスも期待できます。 また勉強して記事にできたらとおもいます。